import cv2
import os,sys
from ultralytics import YOLO
import numpy as np
import pandas as pd
import socket
import time
from datetime import datetime
import threading
index = {'溶解氧':'DO', 'pH值':'pH', '温度':'Temper', '浊度':'Turb', '总磷':'TP', '总氮':'TN', '水体透明度':'WT'}

def recvall(sock, count):
    buf = b''
    while count:
        newbuf = sock.recv(count)
        if not newbuf:
            return None
        buf += newbuf
        count -= len(newbuf)
    return buf

class Process():
# 加载训练好的模型
    def __init__(self,model):
        self.model = model
        self.observes = []
        self.img = {}

    def __call__(self, dur_time, list_, f,client,result_share):
        self.result=[]#用于存放结果
        index_list = list_[0]#取出要求指标
        camera_list = ['index']+list_[1]#取出并拼接出头表
        print(camera_list)
        conn, addr = client.accept()
        call=[]
        for camera in camera_list:
            call.append(threading.Thread(target=self.call,args=(camera,dur_time,f,conn, addr,index_list)))
            call[-1].start()
        for i in call:
            i.join()
        self.ok(dur_time, f, index_list, camera_list, result_share)


    def call(self,camera,dur_time,f,conn, addr,index_list):
        print(camera)
        if camera!= 'index':
            # img = threading.Thread(target=self.get_images,args=(camera,dur_time,f,client))
            self.get_images(camera=camera, dur_time=dur_time, f=f, conn=conn, addr=addr)  # 获取图片
            # img.start()

        res1 = self.process_images(camera)
        res2 = self.get_other_index(index_list, camera)
        if camera == 'index':
            current_time = 'end_time'
            dur_t = 'dur_time'
            f_ = 'pages'
        else:
            current_time = datetime.now()
            dur_t = dur_time
            f_ = f
        self.result.append([camera]+res1+[current_time]+[dur_t,f_]+res2)
        print(self.result)

    def ok(self,dur_time,f,index_list,camera_list,result_queue):
        if len(self.result)==len(camera_list):
            for i,j in enumerate(self.result):
                if j[0]=='index':
                    self.result[0],self.result[i] =self.result[i],self.result[0]
            SUM_index = [0, 0, 0, 0]
            for i in self.result[1:]:
                for j in range(4):
                    SUM_index[j] += int(i[j + 1])
            MEAN_index = [0 for _ in index_list]
            for i in self.result[1:]:
                for j in range(len(MEAN_index)):
                    MEAN_index[j] += float(i[j + 8]) / (len(camera_list) - 1)
            end = ['sum'] + SUM_index + [datetime.now()] + [dur_time, f] + MEAN_index
            self.result.append(end)
            print(self.result)
            result = pd.DataFrame(np.array(self.result), index=None).T
            result_queue.put(result)
            # return result  # 返回csv格式的结果文件


    def get_images(self,camera,dur_time,f,conn, addr):
        images = []
        wait_time = (dur_time/f)*60

        if camera==addr[0]:
            n = 0
            while True:
                try:
                    if n >= f:
                        break
                    length = recvall(conn, 16)  # 接收数据长度
                    if not length:
                        break
                    string_data = recvall(conn, int(length))
                    data = np.frombuffer(string_data, dtype='uint8')
                    frame = cv2.imdecode(data, cv2.IMREAD_COLOR)
                    # cv2.imshow("img",frame)
                    images.append(frame)
                    n += 1
                    print(f"从客户端 {addr} 已接收一张图片.")
                    time.sleep(wait_time)
                except Exception as e:
                    print(f"Exception occurred: {e}")
                    break
        self.img[camera]=images
        # return images

    def get_other_index(self,index_list,camera):
        output = []
        if camera == 'index':
            for i in index_list:
                output.append(index[i])
            return output
        for i in index_list:
            if i == '溶解氧':
                output.append(round(np.random.uniform(10), 2))
            if i == 'pH值':
                output.append(round(np.random.uniform(14), 2))
            if i == '温度':
                output.append(round(np.random.uniform(50), 2))
            if i == '浊度':
                output.append(round(np.random.uniform(30), 2))
            if i == '总磷':
                output.append(round(np.random.uniform(0, 1), 2))
            if i == '总氮':
                output.append(round(np.random.uniform(0, 1), 2))
            if i == '水体透明度':
                output.append(round(np.random.uniform(50), 2))
        return output

    def process_images(self,camera):
        observes=[]
        trained_model = YOLO("../model/" + self.model)  # 调用模型
        if camera == 'index':
            return ['holothurian','echinus','scallop','starfish']
        image_files = self.img[camera]
        # 初始化当前图像的类别计数器
        class_counts = {i: 0 for i in range(4)}
        for img_file in image_files:
            # 读取测试图像
            if img_file is None:
                print(f"Warning: Unable to load image")
                continue
            # cv2.imshow("img",img_file)
            # 使用模型进行推理
            results = trained_model(img_file)


            # 遍历检测结果，统计每种类别的数量
            for result in results:
                for box in result.boxes:
                    class_id = int(box.cls)  # 获取类别ID
                    class_counts[class_id] += 1

                    # 打印当前图像中每种类别的数量
        count_out=list(class_counts.items())
        print(count_out)
        for i in count_out:
            observes.append(i[1])
        return observes
